using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.Domain.Notifications
{
    /// <summary>
    /// 通知仓储接口
    /// </summary>
    public interface INotificationRepository : IRepository<Notification, Guid>
    {
        /// <summary>
        /// 根据接收者ID获取通知列表
        /// </summary>
        Task<List<Notification>> GetByRecipientIdAsync(
            Guid recipientId,
            NotificationType? type = null,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据接收者邮箱获取通知列表
        /// </summary>
        Task<List<Notification>> GetByRecipientEmailAsync(
            string email,
            NotificationType? type = null,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据发送者ID获取通知列表
        /// </summary>
        Task<List<Notification>> GetBySenderIdAsync(
            Guid senderId,
            NotificationType? type = null,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据批次ID获取通知列表
        /// </summary>
        Task<List<Notification>> GetByBatchIdAsync(
            Guid batchId,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据模板ID获取通知列表
        /// </summary>
        Task<List<Notification>> GetByTemplateIdAsync(
            Guid templateId,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据通知类型获取通知列表
        /// </summary>
        Task<List<Notification>> GetByTypeAsync(
            NotificationType type,
            NotificationStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据通知渠道获取通知列表
        /// </summary>
        Task<List<Notification>> GetByChannelAsync(
            NotificationChannel channel,
            NotificationStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据优先级获取通知列表
        /// </summary>
        Task<List<Notification>> GetByPriorityAsync(
            NotificationPriority priority,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据状态获取通知列表
        /// </summary>
        Task<List<Notification>> GetByStatusAsync(
            NotificationStatus status,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取待发送的通知
        /// </summary>
        Task<List<Notification>> GetPendingNotificationsAsync(
            NotificationChannel? channel = null,
            DateTime? beforeTime = null,
            int maxResultCount = 100,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取需要重试的通知
        /// </summary>
        Task<List<Notification>> GetRetryNotificationsAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 100,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取已调度的通知
        /// </summary>
        Task<List<Notification>> GetScheduledNotificationsAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 100,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取过期的通知
        /// </summary>
        Task<List<Notification>> GetExpiredNotificationsAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 100,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取未读的通知
        /// </summary>
        Task<List<Notification>> GetUnreadNotificationsAsync(
            Guid recipientId,
            NotificationType? type = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取未确认的通知
        /// </summary>
        Task<List<Notification>> GetUnconfirmedNotificationsAsync(
            Guid recipientId,
            DateTime? beforeDeadline = null,
            int maxResultCount = 10,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据关联实体获取通知
        /// </summary>
        Task<List<Notification>> GetByRelatedEntityAsync(
            Guid? entityId = null,
            string? entityType = null,
            NotificationStatus? status = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据分类获取通知
        /// </summary>
        Task<List<Notification>> GetByCategoryAsync(
            string category,
            NotificationStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 搜索通知
        /// </summary>
        Task<List<Notification>> SearchAsync(
            string keyword,
            Guid? recipientId = null,
            NotificationType? type = null,
            NotificationStatus? status = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int maxResultCount = 10,
            int skipCount = 0,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取用户的通知统计
        /// </summary>
        Task<NotificationStatistics> GetUserStatisticsAsync(
            Guid userId,
            DateTime? startTime = null,
            DateTime? endTime = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取租户的通知统计
        /// </summary>
        Task<NotificationStatistics> GetTenantStatisticsAsync(
            Guid? tenantId = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取全局通知统计
        /// </summary>
        Task<NotificationStatistics> GetGlobalStatisticsAsync(
            DateTime? startTime = null,
            DateTime? endTime = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查用户是否有未读通知
        /// </summary>
        Task<bool> HasUnreadNotificationsAsync(
            Guid userId,
            NotificationType? type = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取未读通知数量
        /// </summary>
        Task<int> GetUnreadCountAsync(
            Guid userId,
            NotificationType? type = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量更新状态
        /// </summary>
        Task<int> UpdateStatusAsync(
            List<Guid> notificationIds,
            NotificationStatus newStatus,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量标记为已读
        /// </summary>
        Task<int> MarkAsReadAsync(
            List<Guid> notificationIds,
            Guid? userId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量删除
        /// </summary>
        Task<int> DeleteAsync(
            List<Guid> notificationIds,
            Guid? userId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 清理过期通知
        /// </summary>
        Task<int> CleanupExpiredNotificationsAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 1000,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 清理已归档的通知
        /// </summary>
        Task<int> CleanupArchivedNotificationsAsync(
            DateTime? beforeTime = null,
            int maxResultCount = 1000,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取热门通知
        /// </summary>
        Task<List<Notification>> GetPopularNotificationsAsync(
            int maxResultCount = 10,
            DateTime? since = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取最近通知
        /// </summary>
        Task<List<Notification>> GetRecentNotificationsAsync(
            int maxResultCount = 10,
            Guid? userId = null,
            NotificationType? type = null,
            CancellationToken cancellationToken = default);
    }

    /// <summary>
    /// 通知统计信息
    /// </summary>
    public class NotificationStatistics
    {
        /// <summary>
        /// 总通知数
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 按类型统计
        /// </summary>
        public Dictionary<NotificationType, int> CountByType { get; set; } = new();

        /// <summary>
        /// 按状态统计
        /// </summary>
        public Dictionary<NotificationStatus, int> CountByStatus { get; set; } = new();

        /// <summary>
        /// 按渠道统计
        /// </summary>
        public Dictionary<NotificationChannel, int> CountByChannel { get; set; } = new();

        /// <summary>
        /// 按优先级统计
        /// </summary>
        public Dictionary<NotificationPriority, int> CountByPriority { get; set; } = new();

        /// <summary>
        /// 已发送数量
        /// </summary>
        public int SentCount { get; set; }

        /// <summary>
        /// 已送达数量
        /// </summary>
        public int DeliveredCount { get; set; }

        /// <summary>
        /// 失败数量
        /// </summary>
        public int FailedCount { get; set; }

        /// <summary>
        /// 已读数量
        /// </summary>
        public int ReadCount { get; set; }

        /// <summary>
        /// 未读数量
        /// </summary>
        public int UnreadCount { get; set; }

        /// <summary>
        /// 成功率
        /// </summary>
        public double SuccessRate { get; set; }

        /// <summary>
        /// 读取率
        /// </summary>
        public double ReadRate { get; set; }

        /// <summary>
        /// 平均送达时间（毫秒）
        /// </summary>
        public double AverageDeliveryTimeMs { get; set; }

        /// <summary>
        /// 平均读取时间（毫秒）
        /// </summary>
        public double AverageReadTimeMs { get; set; }
    }
}